﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Effects.Effects
{
    /// <summary>
    ///  Simple limiter. Note that this is not a full working effect.
    ///  overloading.
    /// </summary>
    /// <remarks>
    ///  <para>
    ///   This effect is used to limit peaks in the input signal and prevent output from overloading.
    ///   At the moment the implementation is very straightforward, it just maps interval [-2;2] into interval [-1;1].
    ///   Linear mapping (devision by 2) would result into output with lower volume level. 
    ///   Instead of that the class maps [0 ; 0.8] to [0 ; 0.8], [0.8 ; 1] to [0.8 ; 0.9] and [1 ; 2] to [0.9 ; 1]
    ///   (similar for negative part of input and output interval). 
    ///  </para>
    ///  <para>
    ///   On one hand this approach produces slightly distorted signal but on the other it keeps input signal that is in [-0.8 ; 0.8] untouched. 
    ///  </para>
    /// </remarks>
    public class Limiter : Effect
    {
        /// <summary>
        ///  Gets the name of the effect.
        /// </summary>
        public override string Name
        {
            get
            {
                return "Limiter 0.5";
            }
        }

        /// <summary>
        ///  Effects input signal.
        /// </summary>
        /// <param name="data"> Array containing input signal. </param>
        /// <returns> Output signal. </returns>
        public override double[] effect(double[] data)
        {
            double[] outData = new double[data.Length];

            for(int i=0;i<data.Length;i++)
            {
                if (data[i] > 1)
                    outData[i] = 0.9 + (data[i] - 1) / 10;
                else if (data[i] > 0.8)
                    outData[i] = 0.8 + (data[i] - 0.8) / 2;
                else if (data[i] < -1)
                    outData[i] = -0.9 + (data[i] + 1) / 10;
                else if (data[i] < -0.8)
                    outData[i] = -0.8 + (data[i] + 0.8) / 2;
                else 
                    outData[i] = data[i];
            }

           return outData;
        }
    }
}
